From 45d0de90c68101faf5118e8a3d116ed6fd6bfb41 Mon Sep 17 00:00:00 2001 From: =?utf8?q?T=C3=A9o=20Mazars?= Date: Wed, 26 Jun 2013 23:00:05 +0200 Subject: [PATCH] extensions: Add the Y'CbCr ITU-R BT.709 Color Space A variation of the current Y'CbCr (BT.601 or 470?), needed downstream. --- extensions/Makefile.am | 4 +- extensions/ycbcr.c | 258 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 extensions/ycbcr.c diff --git a/extensions/Makefile.am b/extensions/Makefile.am index dca87c0..3954739 100644 --- a/extensions/Makefile.am +++ b/extensions/Makefile.am @@ -31,7 +31,8 @@ ext_LTLIBRARIES = \ sse2-float.la \ sse2-int8.la \ sse2-int16.la \ - two-table.la + two-table.la \ + ycbcr.la cairo_la_SOURCES = cairo.c cairo-tables.h CIE_la_SOURCES = CIE.c @@ -48,6 +49,7 @@ sse2_float_la_SOURCES = sse2-float.c sse2_int8_la_SOURCES = sse2-int8.c sse2_int16_la_SOURCES = sse2-int16.c two_table_la_SOURCES = two-table.c two-table-tables.h +ycbcr_la_SOURCES = ycbcr.c float_la_SOURCES = float.c fast_float_la_SOURCES = fast-float.c diff --git a/extensions/ycbcr.c b/extensions/ycbcr.c new file mode 100644 index 0000000..11db563 --- /dev/null +++ b/extensions/ycbcr.c @@ -0,0 +1,258 @@ +/* babl - dynamically extendable universal pixel conversion library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see + * . + */ + +#include "config.h" + +#include +#include + +#include "babl.h" +#include "base/util.h" + + +static void components (void); +static void models (void); +static void conversions (void); +static void formats (void); + +int init (void); + + +int +init (void) +{ + components (); + models (); + conversions (); + formats (); + + return 0; +} + + +static void +components (void) +{ + babl_component_new ("alpha", NULL); +} + + +static void +models (void) +{ + babl_model_new ( + "name", "Y'CbCr709", + babl_component ("Y'"), + babl_component ("Cb"), + babl_component ("Cr"), + NULL); + + babl_model_new ( + "name", "Y'CbCrA709", + babl_component ("Y'"), + babl_component ("Cb"), + babl_component ("Cr"), + babl_component ("alpha"), + NULL); +} + + +static long +rgba_to_ycbcra709 (char *src, + char *dst, + long n) +{ + while (n--) + { + double red = ((double *) src)[0]; + double green = ((double *) src)[1]; + double blue = ((double *) src)[2]; + double alpha = ((double *) src)[3]; + + double luminance, cb, cr; + + red = linear_to_gamma_2_2 (red); + green = linear_to_gamma_2_2 (green); + blue = linear_to_gamma_2_2 (blue); + + luminance = 0.2126 * red + 0.7152 * green + 0.0722 * blue; + cb = (blue - luminance) / 1.8556; + cr = (red - luminance) / 1.5748; + + ((double *) dst)[0] = luminance; + ((double *) dst)[1] = cb; + ((double *) dst)[2] = cr; + ((double *) dst)[3] = alpha; + + src += sizeof (double) * 4; + dst += sizeof (double) * 4; + } + return n; +} + + +static long +rgba_to_ycbcr709 (char *src, + char *dst, + long n) +{ + while (n--) + { + double red = ((double *) src)[0]; + double green = ((double *) src)[1]; + double blue = ((double *) src)[2]; + + double luminance, cb, cr; + + red = linear_to_gamma_2_2 (red); + green = linear_to_gamma_2_2 (green); + blue = linear_to_gamma_2_2 (blue); + + luminance = 0.2126 * red + 0.7152 * green + 0.0722 * blue; + cb = (blue - luminance) / 1.8556; + cr = (red - luminance) / 1.5748; + + ((double *) dst)[0] = luminance; + ((double *) dst)[1] = cb; + ((double *) dst)[2] = cr; + + src += sizeof (double) * 4; + dst += sizeof (double) * 3; + } + return n; +} + + +static long +ycbcra709_to_rgba (char *src, + char *dst, + long n) +{ + while (n--) + { + double luminance = ((double *) src)[0]; + double cb = ((double *) src)[1]; + double cr = ((double *) src)[2]; + double alpha = ((double *) src)[3]; + + double red, green, blue; + + red = 1.0 * luminance + 0.0 * cb + 1.5748 * cr; + green = 1.0 * luminance - 0.1873 * cb - 0.4681 * cr; + blue = 1.0 * luminance + 1.8556 * cb + 0.0 * cr; + + red = gamma_2_2_to_linear (red); + green = gamma_2_2_to_linear (green); + blue = gamma_2_2_to_linear (blue); + + ((double *) dst)[0] = red; + ((double *) dst)[1] = green; + ((double *) dst)[2] = blue; + ((double *) dst)[3] = alpha; + + src += sizeof (double) * 4; + dst += sizeof (double) * 4; + } + return n; +} + + +static long +ycbcr709_to_rgba (char *src, + char *dst, + long n) +{ + while (n--) + { + double luminance = ((double *) src)[0]; + double cb = ((double *) src)[1]; + double cr = ((double *) src)[2]; + + double red, green, blue; + + red = 1.0 * luminance + 0.0 * cb + 1.5748 * cr; + green = 1.0 * luminance - 0.1873 * cb - 0.4681 * cr; + blue = 1.0 * luminance + 1.8556 * cb + 0.0 * cr; + + red = gamma_2_2_to_linear (red); + green = gamma_2_2_to_linear (green); + blue = gamma_2_2_to_linear (blue); + + ((double *) dst)[0] = red; + ((double *) dst)[1] = green; + ((double *) dst)[2] = blue; + ((double *) dst)[3] = 1.0; + + src += sizeof (double) * 3; + dst += sizeof (double) * 4; + } + return n; +} + + +static void +conversions (void) +{ + babl_conversion_new ( + babl_model ("RGBA"), + babl_model ("Y'CbCr709"), + "linear", rgba_to_ycbcr709, + NULL + ); + babl_conversion_new ( + babl_model ("RGBA"), + babl_model ("Y'CbCrA709"), + "linear", rgba_to_ycbcra709, + NULL + ); + babl_conversion_new ( + babl_model ("Y'CbCrA709"), + babl_model ("RGBA"), + "linear", ycbcra709_to_rgba, + NULL + ); + babl_conversion_new ( + babl_model ("Y'CbCr709"), + babl_model ("RGBA"), + "linear", ycbcr709_to_rgba, + NULL + ); +} + + +static void +formats (void) +{ + babl_format_new ( + babl_model ("Y'CbCrA709"), + babl_type ("float"), + babl_component ("Y'"), + babl_type ("float"), + babl_component ("Cb"), + babl_component ("Cr"), + babl_component ("alpha"), + NULL); + + babl_format_new ( + babl_model ("Y'CbCr709"), + babl_type ("float"), + babl_component ("Y'"), + babl_type ("float"), + babl_component ("Cb"), + babl_component ("Cr"), + NULL); +} -- 2.30.2